﻿using Auth.Domain.Entities;
using Auth.Infrastructure.Repositories;
using AutoMapper;
using Newtonsoft.Json;
using Process.Domain.DTO.InputDTO;
using Process.Domain.DTO.InputDTO.Audit;
using Process.Domain.DTO.OutDTO;
using Process.Domain.Entities;
using Process.Domain.Steps;
using Process.Infrastructure.Repositories;
using Process.Result;
using Produce.Domain.Entities;
using Produce.Infrastructure.Repositories;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using WorkflowCore.Interface;
using WorkflowCore.Models.DefinitionStorage.v1;
using WorkflowCore.Services;
using WorkflowCore.Services.DefinitionStorage;


namespace Process.Application.WorkflowDefintion
{
    public class WorkflowDefinition: IWrokflowDefintion
    {
        private readonly IProcessRepository<WorkflowDefinitionModel> _processRepository;
        private readonly IMapper _Mapper;
        private readonly IWorkflowHost workflowHost;
        private readonly IDefinitionLoader definitionLoader;
        private readonly IWorkflowRegistry workflowRegistry;
        private readonly IProcessRepository<OperationModel> _operationRepository;
        private readonly IProcessRepository<WorkflowDefinitionModel> _definitionprocessRepository;
        private readonly IProcessRepository<ProcessAuditModel> _processaudtiModel;
        private readonly IAuthRepository<UserModel> _usermodel;
        public WorkflowDefinition(IProcessRepository<WorkflowDefinitionModel> processRepository,IMapper Mapper, IWorkflowHost workflowHost, IDefinitionLoader definitionLoader, IWorkflowRegistry workflowRegistry,IProcessRepository<OperationModel> operationRepository, IProcessRepository<WorkflowDefinitionModel> definitionprocessRepository, IProcessRepository<ProcessAuditModel> processaudtiModel, IAuthRepository<UserModel> usermodel) 
        {
            _processRepository = processRepository;
            _Mapper = Mapper;
            this.workflowHost = workflowHost;
            this.definitionLoader = definitionLoader;
            this.workflowRegistry = workflowRegistry;
            _operationRepository = operationRepository;
            _definitionprocessRepository = definitionprocessRepository;
            _processaudtiModel = processaudtiModel;
            _usermodel = usermodel;
        }
        /// <summary>
        /// 添加工作流定义（工作流引擎）
        /// </summary>
        /// <param name="workflow"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public void AddWorkflow(WorkflowDefinitionModel model)
        {
            if (workflowRegistry.IsRegistered(model.DefinitionId, model.Version))
            {
                return;
            }

            DefinitionSourceV1 Source = new DefinitionSourceV1()
            {
                Id = model.DefinitionId,
                Version = model.Version,
                DataType = $"{typeof(Dictionary<string, object>).FullName},{typeof(Dictionary<string, object>).Assembly.FullName}",
                Description = model.Title,
            };

            // 反序列化步骤
            var Steps = JsonConvert.DeserializeObject<List<StepNode>>(model.Steps, new JsonSerializerSettings
            {
                StringEscapeHandling = StringEscapeHandling.Default
            });

            if (Steps.Any())
            {
                // 过滤掉可能存在的开始和结束节点
                var filteredSteps = Steps
                    .Where(s => !s.StepId.Equals("start", StringComparison.OrdinalIgnoreCase) &&
                              !s.StepId.Equals("end", StringComparison.OrdinalIgnoreCase) &&
                              !s.StepId.Equals(nameof(StartStep), StringComparison.OrdinalIgnoreCase) &&
                              !s.StepId.Equals(nameof(EndStep), StringComparison.OrdinalIgnoreCase))
                    .ToList();

                // 如果过滤后没有步骤了，直接返回
                if (!filteredSteps.Any())
                {
                    return;
                }

                // 添加开始步骤
                StepSourceV1 start = new StepSourceV1()
                {
                    Id = nameof(StartStep),
                    Name = "开始",
                    StepType = $"{typeof(StartStep).FullName},{typeof(StartStep).Assembly.FullName}",
                    NextStepId = filteredSteps.First().StepId
                };
                Source.Steps.Add(start);

                // 处理中间步骤之间的连接
                for (int i = 0; i < filteredSteps.Count - 1; i++)
                {
                    filteredSteps[i].StepNextId = filteredSteps[i + 1].StepId;
                }

                // 设置最后一个步骤的下一步为结束步骤
                filteredSteps.Last().StepNextId = nameof(EndStep);

                // 添加所有过滤后的步骤
                foreach (var i in filteredSteps)
                {
                    StepSourceV1 audit = new StepSourceV1()
                    {
                        Id = i.StepId,
                        Name = i.StepName,
                        StepType = $"{typeof(AuditStep).FullName},{typeof(AuditStep).Assembly.FullName}",
                        NextStepId = i.StepNextId,
                    };
                    audit.Inputs.TryAdd("UserAuditId", $"\"{i.AuditUserId}\"");
                    audit.Inputs.TryAdd("UserAuditName", $"\"{i.AuditUserName}\"");

                    Source.Steps.Add(audit);
                }

                // 添加结束步骤
                StepSourceV1 end = new StepSourceV1()
                {
                    Id = nameof(EndStep),
                    Name = "结束",
                    StepType = $"{typeof(EndStep).FullName},{typeof(EndStep).Assembly.FullName}"
                };
                Source.Steps.Add(end);
            }

            var json = JsonConvert.SerializeObject(Source, new JsonSerializerSettings
            {
                StringEscapeHandling = StringEscapeHandling.Default,
                Formatting = Formatting.None
            });

            definitionLoader.LoadDefinition(json, Deserializers.Json);
        }

        /*
        /// <summary>
        /// 添加工作流定义（数据库）
        /// </summary>
        /// <param name="workflow">参数</param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        //public ApiResult<int> AddWorkflowDefinition(AddWorkflowDefinitionDTO workflow)
        //{
        //    try
        //    {
        //        Console.WriteLine($"开始处理工作流定义: {workflow.Title}, 版本: {workflow.Version}");
                
        //        // 1. 解析传入的工艺步骤
        //        List<StepNode> operationSteps;
        //        try 
        //        {
        //            operationSteps = workflow.Steps;
                    
        //            Console.WriteLine($"解析工艺步骤成功，共 {operationSteps?.Count ?? 0} 个步骤");
        //        }
        //        catch (Exception ex)
        //        {
        //            Console.WriteLine($"解析工艺步骤失败: {ex.Message}");
        //            return new ApiResult<int> { 
        //                Success = ResultCode.Fail, 
        //                Message = $"解析工艺步骤失败: {ex.Message}", 
        //                Data = 0 
        //            };
        //        }
                
        //        if (operationSteps == null || !operationSteps.Any())
        //        {
        //            Console.WriteLine("工艺步骤为空");
        //            return new ApiResult<int> { 
        //                Success = ResultCode.Fail, 
        //                Message = "工艺步骤不能为空", 
        //                Data = 0 
        //            };
        //        }

        //        // 2. 创建最终要保存的工序步骤列表
        //        List<StepNode> processSteps = new List<StepNode>();

        //        // 3. 按顺序处理每个工艺，找出其对应的工序集
        //        foreach (var operationStep in operationSteps)
        //        {
        //            Console.WriteLine($"处理工艺步骤: {operationStep.StepName}, ID: {operationStep.StepId}");
                    
        //            // 根据StepId(工艺编码)查找对应工艺
        //            var operation = _operationRepository.GetValue().Where(x => x.OperationCode == operationStep.StepId).FirstOrDefault();
        //            if (operation == null)
        //            {
        //                Console.WriteLine($"未找到工艺编码为 {operationStep.StepId} 的工艺");
        //                continue;
        //            }

        //            // 解析工艺中的工序步骤
        //            List<StepNode> operationProcessSteps;
        //            try
        //            {
        //                operationProcessSteps = JsonConvert.DeserializeObject<List<StepNode>>(operation.Steps, new JsonSerializerSettings 
        //                { 
        //                    StringEscapeHandling = StringEscapeHandling.Default 
        //                })!;
                        
        //                Console.WriteLine($"工艺 {operation.OperationName} 包含 {operationProcessSteps?.Count ?? 0} 个工序步骤");
        //            }
        //            catch (Exception ex)
        //            {
        //                Console.WriteLine($"解析工艺 {operation.OperationName} 的工序步骤失败: {ex.Message}");
        //                continue;
        //            }
                    
        //            if (operationProcessSteps == null || !operationProcessSteps.Any())
        //            {
        //                Console.WriteLine($"工艺 {operation.OperationName} 没有工序步骤");
        //                continue;
        //            }

        //            // 添加工艺对应的工序集到最终列表
        //            processSteps.AddRange(operationProcessSteps);
        //        }

        //        if (!processSteps.Any())
        //        {
        //            Console.WriteLine("没有找到任何有效的工序步骤");
        //            return new ApiResult<int> { 
        //                Success = ResultCode.Fail, 
        //                Message = "没有找到任何有效的工序步骤", 
        //                Data = 0 
        //            };
        //        }

        //        Console.WriteLine($"合并后共有 {processSteps.Count} 个工序步骤");

        //        // 4. 处理工序之间的连接关系(确保前一个工序连接到下一个)
        //        //for (int i = 0; i < processSteps.Count - 1; i++)
        //        //{
        //        //    processSteps[i].StepNextId = processSteps[i + 1].StepId;
        //        //}

        //        //// 5. 最后一个工序连接到结束节点
        //        //if (processSteps.Any())
        //        //{
        //        //    processSteps.Last().StepNextId = "EndStep";
        //        //}


        //        for (int i = 0; i < processSteps.Count - 1; i++)
        //        {
        //            // 如果当前步骤是结束步骤，其StepNextId应为空
        //            if (processSteps[i].StepId.ToLower() == "end")
        //            {
        //                processSteps[i].StepNextId = "";
        //            }
        //            else
        //            {
        //                processSteps[i].StepNextId = processSteps[i + 1].StepId;
        //            }
        //        }

        //        // 5. 最后一个工序连接到结束节点
        //        if (processSteps.Any())
        //        {
        //            // 如果最后一个步骤是结束步骤，其StepNextId应为空
        //            if (processSteps.Last().StepId.ToLower() == "end")
        //            {
        //                processSteps.Last().StepNextId = "";
        //            }
        //            else
        //            {
        //                processSteps.Last().StepNextId = "EndStep";
        //            }
        //        }

        //        // 6. 创建WorkflowDefinitionModel并保存
        //        var model = _Mapper.Map<WorkflowDefinitionModel>(workflow);
        //        model.Id = GenerateSnowflakeId();
        //        model.Steps = JsonConvert.SerializeObject(processSteps, new JsonSerializerSettings
        //        {
        //            StringEscapeHandling = StringEscapeHandling.Default,
        //            Formatting = Formatting.None
        //        });

        //        int result = _processRepository.Create(model);
        //        Console.WriteLine($"保存工作流定义 {(result > 0 ? "成功" : "失败")}");
                
        //        return new ApiResult<int>
        //        {
        //            Success = result > 0 ? ResultCode.Success : ResultCode.Fail,
        //            Message = result > 0 ? "添加成功" : "添加失败",
        //            Data = result
        //        };
        //    }
        //    catch (Exception ex)
        //    {
        //        Console.WriteLine($"添加工作流定义异常: {ex.Message}");
        //        return new ApiResult<int> { 
        //            Success = ResultCode.Fail, 
        //            Message = $"添加工作流定义失败: {ex.Message}", 
        //            Data = 0 
        //        };
        //    }
        //}
        */

        public ApiResult<int> AddWorkflowDefinition(AddWorkflowDefinitionDTO workflow)
        {
            try
            {
                Console.WriteLine($"开始处理工作流定义: {workflow.Title}, 版本: {workflow.Version}");

                // 1. 解析传入的工艺步骤
                List<StepNode> operationSteps;
                try
                {
                    operationSteps = workflow.Steps;
                    Console.WriteLine($"解析工艺步骤成功，共 {operationSteps?.Count ?? 0} 个步骤");
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"解析工艺步骤失败: {ex.Message}");
                    return new ApiResult<int>
                    {
                        Success = ResultCode.Fail,
                        Message = $"解析工艺步骤失败: {ex.Message}",
                        Data = 0
                    };
                }

                if (operationSteps == null || !operationSteps.Any())
                {
                    Console.WriteLine("工艺步骤为空");
                    return new ApiResult<int>
                    {
                        Success = ResultCode.Fail,
                        Message = "工艺步骤不能为空",
                        Data = 0
                    };
                }

                // 2. 创建最终要保存的工序步骤列表
                List<StepNode> processSteps = new List<StepNode>();

                // 3. 按顺序处理每个工艺，找出其对应的工序集
                foreach (var operationStep in operationSteps)
                {
                    Console.WriteLine($"处理工艺步骤: {operationStep.StepName}, ID: {operationStep.StepId}");

                    // 根据StepId(工艺编码)查找对应工艺
                    var operation = _operationRepository.GetValue().Where(x => x.OperationCode == operationStep.StepId).FirstOrDefault();
                    if (operation == null)
                    {
                        Console.WriteLine($"未找到工艺编码为 {operationStep.StepId} 的工艺");
                        continue;
                    }

                    // 解析工艺中的工序步骤
                    List<StepNode> operationProcessSteps;
                    try
                    {
                        operationProcessSteps = JsonConvert.DeserializeObject<List<StepNode>>(operation.Steps, new JsonSerializerSettings
                        {
                            StringEscapeHandling = StringEscapeHandling.Default
                        })!;

                        Console.WriteLine($"工艺 {operation.OperationName} 包含 {operationProcessSteps?.Count ?? 0} 个工序步骤");
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"解析工艺 {operation.OperationName} 的工序步骤失败: {ex.Message}");
                        continue;
                    }

                    if (operationProcessSteps == null || !operationProcessSteps.Any())
                    {
                        Console.WriteLine($"工艺 {operation.OperationName} 没有工序步骤");
                        continue;
                    }

                    // 过滤掉开始和结束节点，只保留实际工序
                    var filteredSteps = operationProcessSteps
                        .Where(s => !s.StepId.Equals("start", StringComparison.OrdinalIgnoreCase) &&
                                   !s.StepId.Equals("end", StringComparison.OrdinalIgnoreCase))
                        .ToList();

                    // 添加工艺对应的工序集到最终列表
                    processSteps.AddRange(filteredSteps);
                }

                if (!processSteps.Any())
                {
                    Console.WriteLine("没有找到任何有效的工序步骤");
                    return new ApiResult<int>
                    {
                        Success = ResultCode.Fail,
                        Message = "没有找到任何有效的工序步骤",
                        Data = 0
                    };
                }

                Console.WriteLine($"合并后共有 {processSteps.Count} 个工序步骤");

                // 4. 处理工序之间的连接关系
                for (int i = 0; i < processSteps.Count - 1; i++)
                {
                    processSteps[i].StepNextId = processSteps[i + 1].StepId;
                }

                // 5. 最后一个工序连接到结束节点
                if (processSteps.Any())
                {
                    processSteps.Last().StepNextId = "EndStep";
                }

                // 直接使用处理后的工序步骤列表，不再添加开始和结束节点
                var model = _Mapper.Map<WorkflowDefinitionModel>(workflow);
                model.Id = GenerateSnowflakeId();
                model.Steps = JsonConvert.SerializeObject(processSteps, new JsonSerializerSettings
                {
                    StringEscapeHandling = StringEscapeHandling.Default,
                    Formatting = Formatting.None
                });
                AddWorkflow(model);
                int result = _processRepository.Create(model);
                Console.WriteLine($"保存工作流定义 {(result > 0 ? "成功" : "失败")}");

                return new ApiResult<int>
                {
                    Success = result > 0 ? ResultCode.Success : ResultCode.Fail,
                    Message = result > 0 ? "添加成功" : "添加失败",
                    Data = result
                };
            }
            catch (Exception ex)
            {
                Console.WriteLine($"添加工作流定义异常: {ex.Message}");
                return new ApiResult<int>
                {
                    Success = ResultCode.Fail,
                    Message = $"添加工作流定义失败: {ex.Message}",
                    Data = 0
                };
            }
        }

        /// <summary>
        /// 待审批数据
        /// </summary>
        /// <param name="audit">待审批</param>
        /// <returns></returns>
        public Apipaging<ShowAuditDataOut> ShowAuditDataClick(ShowAuditData audit)
        {
            Apipaging<ShowAuditDataOut> api = new Apipaging<ShowAuditDataOut>();
            var AuditUserName = _usermodel.GetAll().Where(x => x.UserName == audit.AuditUserName).FirstOrDefault()!.RealName;
            var data=_processaudtiModel.GetValue().Where(x => x.IsDeleted==false&&x.AuditUserName== AuditUserName&&x.Status=="审核中");
            if (!string.IsNullOrEmpty(audit.WorkflowId))
            { 
                data = data.Where(x => x.WorkflowId == audit.WorkflowId);
            }
            if (!string.IsNullOrEmpty(audit.StepName))
            {
                data = data.Where(x => x.StepName == audit.StepName);
            }
            api.TotalCount= data.Count();
            api.TotalPages=(int)Math.Ceiling(api.TotalCount * 1.0 / audit.PagSize);
            var list=data.OrderBy(x => x.Id).Skip((audit.PagIndex - 1) * audit.PagSize).Take(audit.PagSize).ToList();
            var pagingdata=_Mapper.Map<List<ShowAuditDataOut>>(list);
            api.PagingData = pagingdata;
            api.Success=ResultCode.Success;
            api.Message="查询成功";
            return api;
        }

        /// <summary>
        /// 显示工序审批记录
        /// </summary>
        /// <param name="auditProcess"></param>
        /// <returns></returns>
        public Apipaging<ShowAuditProcessDTO> ShowAuditProcess(AuditProcess auditProcess)
        {
            Apipaging<ShowAuditProcessDTO> api = new Apipaging<ShowAuditProcessDTO>();
            var data = _processaudtiModel.GetValue().Where(x => x.IsDeleted==false);
            var  list= _Mapper.Map<List<ShowAuditProcessDTO>>(data);
            if (!string.IsNullOrEmpty(auditProcess.WorkflowId))
            { 
                list = list.Where(x => x.WorkflowId == auditProcess.WorkflowId).ToList();
            }
            if (!string.IsNullOrEmpty(auditProcess.StepName))
            { 
                list = list.Where(x => x.StepName == auditProcess.StepName).ToList();
            }
            api.TotalCount = list.Count();
            api.TotalPages = (int)Math.Ceiling(api.TotalCount * 1.0 / auditProcess.PagSize);
            var audit= list.OrderBy(x => x.Id).Skip((auditProcess.PagIndex - 1) * auditProcess.PagSize).Take(auditProcess.PagSize).ToList();
            api.PagingData = audit;
            return new Apipaging<ShowAuditProcessDTO>
            {
                Success = ResultCode.Success,
                Message = "获取工作流定义成功",
                PagingData = audit
            };
        }

        /// <summary>
        /// 获取工作流定义
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public  WorkflowDefinitionModel StartWorkflow(long Id)
        {
            var data = _definitionprocessRepository.GetValue().Where(x => x.DefinitionId == Id.ToSqlValue()).FirstOrDefault();            
            return data;
            
        }

        /// <summary>
        /// 生成雪花ID
        /// </summary>
        /// <returns>唯一ID</returns>
        private long GenerateSnowflakeId()
        {
            // 简化版雪花ID实现
            long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
            long machineId = 1; // 机器ID
            long sequence = new Random().Next(0, 4095); // 序列号

            return ((timestamp - 1288834974657L) << 22) | (machineId << 12) | sequence;
        }

    }
}
